package com.ruoyi.business.service.impl;

import com.alibaba.fastjson.JSON;
import com.ruoyi.business.domain.CarPackageAudit;
import com.ruoyi.business.domain.ServiceItem;
import com.ruoyi.business.service.*;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.utils.ShiroUtils;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class TodoServiceImpl implements ITodoService {

    @Autowired
    private IProcessService processService;
    @Autowired
    private ICarPackageAuditService carPackageAuditService;
    @Autowired
    private IDefinitionNodeService definitionNodeService;
    @Autowired
    private IServiceItemService serviceItemService;

    @Override
    public TableDataInfo selectTodoList(CarPackageAudit carPackageAudit) {
        //查询总记录数
        long count = processService.getTaskCountByDefinitionKeyAndUserId(CarPackageAudit.DEFINITION_KEY,
                ShiroUtils.getSysUser().getUserId().toString());
        TableDataInfo resultData = new TableDataInfo();
        resultData.setCode(0);
        if (count == 0){
            return resultData;
        }
        List<CarPackageAudit> carPackageAuditList = new ArrayList<>();
        //封装分页参数
        PageDomain pageDomain = TableSupport.buildPageRequest();
        int startIndex = (pageDomain.getPageNum() - 1 ) * pageDomain.getPageSize();

        //1．查询指定流程（流程定义key)和用户id，查询该用户在
        //        resultData.setTotal(count);该流程下所有需要处理的任务（分页参数)=〉任务列表 List<Task>
        List<Task> taskList = processService.getTaskListByDefinitionKeyAndUserId(CarPackageAudit.DEFINITION_KEY,
                                                                                ShiroUtils.getSysUser().getUserId().toString(),
                                                                                startIndex,
                                                                                pageDomain.getPageSize()
        );
        //2．遍历任务列表，获取每一个任务对应的流程实例，通过流程实例获取到 businessKey =>CarPackageAudit.id
        for (Task task : taskList) {
            ProcessInstance processInstance = processService.getProcessInstanceById(task.getProcessInstanceId());
            String businessKey = processInstance.getBusinessKey();
            //3．基于businessKey获取审核记录对象
            CarPackageAudit audit = carPackageAuditService.selectCarPackageAuditById(Long.parseLong(businessKey));
            //4．为审核记录对象设置当前任务id和任务名称
            audit.setTaskId(task.getId());
            audit.setTaskName(task.getName());
            carPackageAuditList.add(audit);
        }
        resultData.setRows(carPackageAuditList);
        return resultData;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void taskAudit(String taskId, boolean auditStatus, String comment) {
        //获取任务对象
        Task task = processService.getTaskById(taskId);
        //获取实例对象
        ProcessInstance instance = processService.getProcessInstanceById(task.getProcessInstanceId());
        // 需求 : 审批指定任务
        // 1.  任务相关操作 (朝朝任务 领取任务  添加批注  完成任务)
        processService.claimAndCompleteTask(task, auditStatus, comment);
        // 2.  获取下一个运行中的节点 (判断流程是否结束)  根据实例id
        Long businessKey = Long.parseLong(instance.getBusinessKey());
        List<Task> nextTaskList = processService.getTaskByInstanceId(instance.getId());
        // 获取审核记录对象
        CarPackageAudit audit = carPackageAuditService.selectCarPackageAuditById(businessKey);
        // 3.  如果有节点
        if (!CollectionUtils.isEmpty(nextTaskList)) {
            Task nextTask = nextTaskList.get(0);
            // 3.1 判断审核状态为 同意还是 拒绝
            if (auditStatus) {
                // 3.2 如果状态为同意
                // 3.2.1 根据当前(最新节点) 节点的 key 查询最新列表
                List<SysUser> auditors = definitionNodeService.selectAuditorsByNodeKey(nextTask.getTaskDefinitionKey());
                List<String> auditorNames = new ArrayList<>();
                // 3.2.2 为任务添加候选人
                for (SysUser auditor : auditors) {
                    auditorNames.add(auditor.getUserName());
                    processService.setTaskCandidateUser(nextTask.getId(), auditor.getUserId().toString());
                }
                // 3.2.3 更新审核记录中审核人字段
                audit.setAuditors(JSON.toJSONString(auditorNames));
            } else {
                // 3.3 如果状态为拒绝
                // 3.3.1 将当前任务的候选人 设置为审核的发起人
                audit.setAuditors(audit.getCreateByName());
                // 将任务的候选人设置为 发起人
                processService.setTaskCandidateUser(nextTask.getId(), audit.getCreateBy());

                // 3.3.2 将审核对象的状态修改为审核拒绝
                audit.setStatus(CarPackageAudit.STATUS_REJECT);
            }
        } else {
            // 4.  没有节点 (审核通过)
            // 4.1 修改审核对象状态  审核人
            audit.setStatus(CarPackageAudit.STATUS_PASS);
            audit.setAuditors("");
            ServiceItem serviceItem = audit.getServiceItem();
            // 4.2 修改服务项 状态为审核通过
            serviceItemService.updateAuditStatus(serviceItem.getId(), ServiceItem.AUDITSTATUS_AUDITING, ServiceItem.AUDITSTATUS_APPROVED);
        }
        // 审核记录对象的更新
        carPackageAuditService.updateCarPackageAudit(audit);
    }

    @Override
    public void updateServiceItem(ServiceItem serviceItem, Long carPackageAuditId) {
        //修改服务项
        serviceItemService.updateAuditingServiceItem(serviceItem);
        //修改审核记录中的服务项
        CarPackageAudit carPackageAudit = new CarPackageAudit();
        carPackageAudit.setId(carPackageAuditId);
        carPackageAudit.setServiceItemInfo(JSON.toJSONString(serviceItem));
        carPackageAuditService.updateCarPackageAudit(carPackageAudit);
    }

    @Override
    public void reApply(String taskId, String carPackageAuditId) {
        CarPackageAudit carPackageAudit = carPackageAuditService.selectCarPackageAuditById(Long.parseLong(carPackageAuditId));

        //覆盖流程变量
        BigDecimal discountPrice = carPackageAudit.getServiceItem().getDiscountPrice();//获取到改变后的金额
        Map<String, Object> variables = new HashMap<>();
        variables.put("money", discountPrice.doubleValue());
        //完成任务
        processService.claimAndCompleteTask(taskId,variables,carPackageAudit.getCreateByName() + "重新发起了审核" );
        //获取下一任务
        List<Task> taskList = processService.getTaskByInstanceId(carPackageAudit.getInstanceId());
        if (!CollectionUtils.isEmpty(taskList)){
            Task task = taskList.get(0);
            //为下一任务设置候选人
            List<SysUser> auditors = definitionNodeService.selectAuditorsByNodeKey(task.getTaskDefinitionKey());
            List<String> auditorNames = new ArrayList<>();
            for (SysUser auditor : auditors) {
                processService.setTaskCandidateUser(task.getId(),auditor.getUserId().toString());
                auditorNames.add(auditor.getUserName());
            }
            //修改审核记录的状态和候选人
            carPackageAudit.setStatus(CarPackageAudit.STATUS_IN_ROGRESS);
            carPackageAudit.setAuditors(JSON.toJSONString(auditorNames));
            carPackageAuditService.updateCarPackageAudit(carPackageAudit);
        }
    }
}
